<template>
  <div :class="{ show: isShow }" class="header-search">
    <svg-icon
      icon-class="search"
      @click.stop="onShowClick"
      class="search-icon"
      id="guide-search"
    ></svg-icon>
    <el-select
      ref="headerSearchSelectRef"
      v-model="search"
      filterable
      remote
      reserve-keyword
      default-first-option
      placeholder="search"
      :remote-method="querySearch"
      class="header-search-select"
      @change="onSelectChange"
    >
      <el-option
        v-for="option in searchOptions"
        :key="option.item.path"
        :label="option.item.title.join('>')"
        :value="option.item.path"
      />
    </el-select>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch } from "vue";
import { useGenerateRoutes, ISearchPoolItem } from "./useGenerateRoutes";
import SvgIcon from "@/components/SvgIcon/index.vue";
import type { FormInstance } from "element-plus";
import Fuse from "fuse.js";
import { constantRoutes } from "@/router";
import { useRouter, RouteRecordRaw } from "vue-router";

// 显示搜索框s
const isShow = ref<boolean>(false);
const headerSearchSelectRef = ref<FormInstance>();
const onShowClick = () => {
  isShow.value = !isShow.value;
};

// 获取路由菜单
let searchPool = useGenerateRoutes(constantRoutes);

// 初始化fuses
let fuse: any;
const initFuse = (searchPool: Array<ISearchPoolItem>) => {
  fuse = new Fuse(searchPool, {
    // 是否按优先级进行排序
    shouldSort: true,
    // 匹配算法放弃的时机， 阈值 0.0 需要完美匹配（字母和位置），阈值 1.0 将匹配任何内容。
    threshold: 0.4,
    // 匹配长度超过这个值的才会被认为是匹配的
    minMatchCharLength: 1,
    // 将被搜索的键列表。 这支持嵌套路径、加权搜索、在字符串和对象数组中搜索。
    // name：搜索的键
    // weight：对应的权重
    keys: [
      {
        name: "title",
        weight: 0.7,
      },
      {
        name: "path",
        weight: 0.3,
      },
    ],
  });
};

initFuse(searchPool);
// 搜索
const search = ref<string>("");
const searchOptions = ref<ISearchPoolItem[]>([]);

const querySearch = (q: string) => {
  if (q !== "") {
    searchOptions.value = fuse.search(q);
  } else {
    searchOptions.value = [];
  }
};

// 关闭

const onClose = () => {
  isShow.value = false;
  searchOptions.value = [];
  search.value = "";
};

/**
 * 监听 search 打开，处理 close 事件
 */
watch(isShow, (val) => {
  if (val) {
    headerSearchSelectRef.value.focus();
    document.body.addEventListener("click", onClose);
  } else {
    headerSearchSelectRef.value.blur();
    document.body.removeEventListener("click", onClose);
  }
});

// 选择搜索结果
const router = useRouter();
const onSelectChange = (path: string) => {
  router.push(path);
  onClose();
};
</script>

<style lang="scss" scoped>
.header-search {
  font-size: 0 !important;
  .search-icon {
    cursor: pointer;
    font-size: 18px;
    vertical-align: middle;
  }

  .header-search-select {
    font-size: 18px;
    transition: width 0.2s;
    width: 0;
    overflow: hidden;
    background: transparent;
    border-radius: 0;
    display: inline-block;
    vertical-align: middle;

    &.el-select {
      --el-select-border-color-hover: none;
      --el-select-input-focus-border-color: none;
    }
    :deep .el-input__wrapper {
      padding: 1px 0;
      box-shadow: none;
    }

    :deep .el-input__inner {
      border-radius: 0;
      border: 0;
      padding-left: 0;
      padding-right: 0;
      box-shadow: none !important;
      border-bottom: 1px solid #d9d9d9;
      vertical-align: middle;
    }
  }
  &.show {
    .header-search-select {
      width: 210px;
      margin-left: 10px;
    }
  }
}
</style>
